import { JXBattleAnalysis } from "./JXBattleAnalysis";
import { JXBattleCb } from './JXBattleCb';
import { JXBattleEvt, JXBtlArrIx, JXBtlBEM, JXBtlCamp, JXBtlPs } from './JXBattleDefine';

/** 文字战报帮助类 */
export default class BattleTextParse {

    /** 事件汉化 */
    public static evtNames = {
        [JXBattleEvt.START]: '开始',
        [JXBattleEvt.ROLE_BEGIN]: '角色开始行动',
        [JXBattleEvt.ROLE_SKILL_PREPARE]: '角色技能进入准备回合',
        [JXBattleEvt.ROLE_SKILL_PRESS]: '角色释放技能',
        [JXBattleEvt.ROLE_SKILL_PRESS_END]: '角色技能释放结束',
        [JXBattleEvt.ROLE_SKILL_BREAK]: '角色技能被打断',
        [JXBattleEvt.ROLE_COM_ATK]: '角色发起普通攻击',
        [JXBattleEvt.ROLE_CONTRLED]: "角色被控制",
        [JXBattleEvt.ROLE_SKILL_HURT]: '角色受到技能攻击',
        [JXBattleEvt.ROLE_SKILL_ADDHP]: '角色受到回血',
        [JXBattleEvt.ROLE_SKILL_ADDMAXHP]: "角色最大生命值增加",
        [JXBattleEvt.ROLE_ATK_2_HP]: '角色吸血',
        [JXBattleEvt.ROLE_HURT_2_ATK]: '角色反弹伤害',
        /** 角色输出转护盾 */
        [JXBattleEvt.ROLE_ATK_2_PROTECT]: '角色输出吸盾',
        /** 角色受伤转血量 */
        [JXBattleEvt.ROLE_HURT_2_HP]: '角色受伤回血',
        /** 角色受伤转护盾 */
        [JXBattleEvt.ROLE_HURT_2_PROTECT]: '角色受伤转护盾',

        [JXBattleEvt.ROLE_ADD_BUFF]: '角色BUFF目标锁定', // [uuid, 释放者key，作用者key，effectId]
        [JXBattleEvt.ROLE_PREPARE_BUFF]: '角色BUFF准备中', // [uuid, 准备回合]
        [JXBattleEvt.ROLE_REMOVE_BUFF]: '角色BUFF移除',

        [JXBattleEvt.ROLE_END]: '角色行动结束',
        [JXBattleEvt.ROLE_DIE]: '角色死亡',
        [JXBattleEvt.ROLE_RELIFE]: '角色复活',

        /** BUFF状态 */
        [JXBattleEvt.CLEAR_LOCK_HP]: '清除锁血状态',
        [JXBattleEvt.LOCK_HP_EFFECT]: '当前角色锁血中',
        [JXBattleEvt.LIFE_TIME_CHANGE]: 'BUFF持续时间变更',
        [JXBattleEvt.DETONATED_BUFF]: 'BUFF效果引爆',
        [JXBattleEvt.HURT_BARKS]: "进攻军营",
        [JXBattleEvt.END_FIGHT]: '结束战斗',
    }

    /** 技能类型汉化 */
    public static skillTypeName = [
        "全局技",
        "主动技",
        "被动技",
        "追击技",
        "反击技",
    ]

    /** 多语言翻译接口 */
    public static i18n: { (key: string): string } = (key: string) => key;

    /**
     * 获取文字战报
     * @param ans 战报对象
     * @param withConsole 是否控制台输出
     */
    public static getTextReport(heroId: string, ans: JXBattleAnalysis, withConsole: boolean = false) {
        let str = "";
        let names = this.getRoleNames(ans);
        let cmd = ans.DPL_getCurRecord(heroId, false);
        if (!cmd) return;
        switch (cmd[JXBtlArrIx.Zero]) {
            /** 开始 */
            case JXBattleEvt.START:
                {
                    let local = "开始战斗播报";
                    str += local
                    withConsole && console.log(local);
                    break;
                }
            /** 角色开始行动 */
            case JXBattleEvt.ROLE_BEGIN:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}开始行动`;
                    str += local
                    withConsole && console.log(local);
                    break;
                }
            /** 角色行动结束 */
            case JXBattleEvt.ROLE_END:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}结束行动`;
                    str += local;
                    if (withConsole) {
                        console.log(local);
                        console.log();
                    }
                    break;
                }

            /** 角色技能进入准备回合 */
            case JXBattleEvt.ROLE_SKILL_PREPARE:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let skillId = cmd[JXBtlArrIx.Two];
                    let local = `${names[id]}的技能${this.getSkillName(skillId)}进入准备`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色释放技能 */
            case JXBattleEvt.ROLE_SKILL_PRESS: //[model, 技能信息] 
                {
                    let ansId = cmd[JXBtlArrIx.One];
                    let skillAns = ans.skillInfos[ansId];
                    let id = skillAns.execer;
                    let skillId = skillAns.skillId;
                    let local = `${names[id]}释放技能${this.getSkillName(skillId)}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色技能释放结束 */
            case JXBattleEvt.ROLE_SKILL_PRESS_END:
                {
                    let ansId = cmd[JXBtlArrIx.One];
                    let skillAns = ans.skillInfos[ansId];
                    let id = skillAns.execer;
                    let skillId = skillAns.skillId;
                    let local = `${names[id]}的技能${this.getSkillName(skillId)}释放结束`;
                    str += local;
                    if (withConsole) {
                        console.log(local);
                        console.log();
                    }
                    break;
                }
            /** 角色技能被打断 */
            case JXBattleEvt.ROLE_SKILL_BREAK:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let skillId = cmd[JXBtlArrIx.Two];
                    let local = `${names[id]}的技能${this.getSkillName(skillId)}施法被打断`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }

            /** 角色发起普通攻击 */
            case JXBattleEvt.ROLE_COM_ATK:    // [伤害信息];
                {
                    let hurtId = cmd[JXBtlArrIx.One];
                    let hurtInfo = ans.hurtInfos[hurtId];
                    let local = `${names[hurtInfo.execer]}对${names[hurtInfo.target]}发起普通攻击\n${names[hurtInfo.target]}血量-${hurtInfo.damage}, 护盾-${hurtInfo.protect}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            case JXBattleEvt.ROLE_CONTRLED:   // [被控制，控制类型]
                {
                    let [_, id, banType, uuid] = cmd;
                    let role = names[id];
                    let effectName = this.getEffectMoldName(banType);
                    let buff = ans.buffInfos[uuid];
                    let skill = ans.skillInfos[buff.insSkillId];
                    let local = `${role}因${names[skill.execer]}施加的${this.getEffectName(buff.buffId)}效果而${effectName}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            case JXBattleEvt.ROLE_IMDE: // [免疫， 免疫类型],
                {
                    let [_, role, i, buffId, buffId1] = cmd;
                    let local = `${names[role]}因${this.getEffectName(buffId1)}无法施加效果${this.getEffectName(buffId)}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }

            /** 角色受到技能攻击 */
            case JXBattleEvt.ROLE_SKILL_HURT: // [伤害信息]
                {
                    let hurtId = cmd[JXBtlArrIx.One];
                    let hurtInfo = ans.hurtInfos[hurtId];
                    let exceRole = names[hurtInfo.execer];
                    let targetRole = names[hurtInfo.target];
                    let buffInfo = ans.buffInfos[hurtInfo.insBuff];
                    let local = `${targetRole}受到来自${exceRole}的${this.getEffectName(buffInfo.buffId)},血量-${hurtInfo.damage}, 护盾-${hurtInfo.protect}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色受到回血 */
            case JXBattleEvt.ROLE_SKILL_ADDHP: // [回血信息]
            /** 角色吸血 */
            case JXBattleEvt.ROLE_HURT_2_HP:  // [吸血信息]
            case JXBattleEvt.ROLE_ATK_2_PROTECT:
            case JXBattleEvt.ROLE_HURT_2_PROTECT:
                {
                    let ansId = cmd[JXBtlArrIx.One];
                    let ansInfo = ans.addHpInfos[ansId];
                    let local = `${names[ansInfo.target]} ${ansInfo.isProtect ? "因为角色受到护盾效果" : "因为角色受到回血效果"} ${ansInfo.isProtect ? "获得护盾" : "恢复血量"}+${ansInfo.addNum}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            case JXBattleEvt.HURT_BARKS: {
                let ansId = cmd[JXBtlArrIx.One];
                let ansInfo = ans.bracksHurtInfos[ansId];
                let local = `${names[ansInfo.execer]} ${this.evtNames[cmd[JXBtlArrIx.Zero]]} 对军营造成${ansInfo.damage}点伤害`;
                str += local;
                withConsole && console.log(local);
                break;
            }
            case JXBattleEvt.ROLE_SKILL_ADDMAXHP: {
                let ansId = cmd[JXBtlArrIx.One];
                let ansInfo = ans.addMaxHpInfos[ansId];
                let exceRole = names[ansInfo.execer];
                let targetRole = names[ansInfo.target];
                let buffInfo = ans.buffInfos[ansInfo.insBuff];
                let local = `${targetRole}受到来自${exceRole}的${this.getEffectName(buffInfo.buffId)},最大血量${ansInfo.oldMaxHp} +${ansInfo.addNum}, `;
                str += local;
                withConsole && console.log(local);
                break;
            }

            /** 角色反弹伤害 */
            case JXBattleEvt.ROLE_HURT_2_ATK:
                {
                    let hurtId = cmd[JXBtlArrIx.One];
                    let hurtInfo = ans.hurtInfos[hurtId];
                    let local = `${names[hurtInfo.target]}受到来自${names[hurtInfo.execer]}的反弹伤害，血量-${hurtInfo.damage}, 护盾-${hurtInfo.protect}`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }

            /** 角色BUFF目标锁定 */
            case JXBattleEvt.ROLE_ADD_BUFF: // [uuid, skillId, nBufId, execer, target]
                {
                    let [_, heroId, uuid, skillId, bufId, excer, target] = cmd;
                    let ansBuff = ans.buffInfos[uuid];
                    let excerName = names[excer];
                    let targetName = names[target];
                    let local = `${targetName}施加了来自${excerName}的${this.getEffectName(bufId)}的效果`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色BUFF准备中 */
            case JXBattleEvt.ROLE_PREPARE_BUFF: // [uuid, 准备回合]
                {
                    let [_, heroId, uuid, rounds] = cmd;
                    let buff = ans.buffInfos[uuid];
                    let local = `${names[buff.target]}的${this.getEffectName(buff.buffId)}效果进入准备，需要${rounds}回合`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色BUFF移除 */
            case JXBattleEvt.ROLE_REMOVE_BUFF: //[heroId,uuid, skillid, nBuffId, execer, target]
                {
                    let [_, excer, uuid, skillid, bufId, target] = cmd;
                    let ansBuff = ans.buffInfos[uuid];
                    let excerName = names[excer];
                    let targetName = names[target];
                    let local = `${targetName}来自${excerName}的${this.getEffectName(bufId)}的效果失效`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }

            /** 角色死亡 */
            case JXBattleEvt.ROLE_DIE:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}死亡`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 角色复活 */
            case JXBattleEvt.ROLE_RELIFE:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}复活`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }

            /** BUFF状态 */
            /** 清除锁血状态 */
            case JXBattleEvt.CLEAR_LOCK_HP:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}失去锁血状态`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 当前角色锁血中 */
            case JXBattleEvt.LOCK_HP_EFFECT:
                {
                    let id = cmd[JXBtlArrIx.One];
                    let local = `${names[id]}开始锁血中`;
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 持续时间延长 */
            case JXBattleEvt.LIFE_TIME_CHANGE:
                {
                    let [_, heroId, uuid, uuids, addRound] = cmd;
                    let buff = ans.buffInfos[uuid];
                    let local = '';
                    for (let i = 0; i < uuids.length; i++) {
                        let targetBuff = ans.buffInfos[uuids[i]];
                        local += `${names[buff.target]}的效果${this.getEffectName(targetBuff.buffId)}持续时间延长${addRound}回合`;
                        if (i! = uuids.length - 1) local += "\n";
                    }
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 效果引爆 */
            case JXBattleEvt.DETONATED_BUFF:
                {
                    let [_, heroId, uuid, effects, addRound] = cmd;
                    let buff = ans.buffInfos[uuid];
                    let local = '';
                    for (let i = 0; i < effects.length; i++) {
                        let targetBuff = ans.buffInfos[effects[i].uuid];
                        local += `${names[buff.target]}的效果${this.getEffectName(targetBuff.buffId)}被引爆`;
                        if (i! = effects.length - 1) local += "\n";
                    }
                    str += local;
                    withConsole && console.log(local);
                    break;
                }
            /** 结束战斗 */
            case JXBattleEvt.END_FIGHT:
                {
                    let local = "结束战斗播报";
                    str += local;
                    withConsole && console.log(local);
                    console.log();
                    break;
                }
        }
        str += "\n";

        return str;
    }
    public static parseCmd(cmd: any[]) {

    }

    public static getSkillName(skillId: number) {
        let skillRaw = JXBattleCb.getSkillData(skillId);
        let name = this.i18n(skillRaw.name);
        return `'${this.skillTypeName[skillRaw.type]}<${name}>'`;
    }

    public static getEffectName(effectId: number) {
        let effectRaw = JXBattleCb.getEffectData(effectId);
        let name = "" + effectRaw.name;
        return `(${name})`;
    }

    public static getRoleNames(analysis: JXBattleAnalysis): { [id: string]: string } {
        let names = Object.create(null);
        for (let i = 0; i < analysis.iBtlTeams.length; i++) {
            for (let j = 0, team = analysis.iBtlTeams[i]; j < team.heroIds.length; j++) {
                let id = team.heroIds[j];
                if (id == JXBtlPs.InvalidString) {
                    continue;
                }
                let heroData: IHeroBtlData = null
                for (let k = 0; k < team.partnerData.length; k++) {
                    if (team.partnerData[k].heroId == id) {
                        heroData = team.partnerData[k];
                        break;
                    }
                }
                if (!heroData) {
                    names[id] = `(未知对象)【ikey = ${id}】`;
                    continue;
                }
                let cardData = JXBattleCb.getCardData(heroData.tableId);
                let name = this.i18n(cardData.name);
                names[id] = `【(${name})[${i == JXBtlCamp.Attacker ? "攻击" : "防守"}${j}]】`;
            }
        }
        let keys = Object.keys(analysis.extras);
        for (let i = 0; i < keys.length; i++) {
            let extra = analysis.extras[keys[i]];
            let fix = "";
            if (extra.camp == JXBtlCamp.NoCamp) {
                fix = "无阵营";
            } else {
                fix = extra.camp == JXBtlCamp.Attacker ? "攻击" : "防守";
            }
            names[keys[i]] = `【(环境)[${fix}${extra.id}]】`
        }

        return names;
    }

    public static getEffectMoldName(mold: number) {
        let str = ""
        switch (mold) {
            case JXBtlBEM.Hurt: str = "伤害"; break;
            case JXBtlBEM.AddHp: str = "治疗"; break;
            case JXBtlBEM.SubPropts: str = "降低属性（固定值）"
            case JXBtlBEM.SubMulPropts: str = "降低属性（百分比）"
            case JXBtlBEM.DBHit: str = "二次普攻"; break;
            case JXBtlBEM.AddPropts: str = "提升属性（固定值）"; break;
            case JXBtlBEM.AddMulPropts: str = "提升属性（百分比）"; break;
            case JXBtlBEM.HurtToHp: str = "输出吸血"; break;
            case JXBtlBEM.HurtToAtk: str = "反弹伤害"; break;
            case JXBtlBEM.RoundActivePropts: str = "生效期间，每回合开始重新计算"; break;
            case JXBtlBEM.BanAttack: str = "禁止普攻"; break;
            case JXBtlBEM.BanSkill: str = "禁止技能"; break;
            case JXBtlBEM.Confusion: str = "敌我不分: 混乱 "; break;
            case JXBtlBEM.Mock: str = "嘲讽目标"; break;
            case JXBtlBEM.BanAddHp: str = "禁止治疗"; break;
            case JXBtlBEM.BanBuff: str = "禁止增益"; break;
            case JXBtlBEM.BanIme: str = "禁止免疫"; break;
            case JXBtlBEM.BanAction: str = "禁止行动"; break;
            case JXBtlBEM.ImDamage: str = "免疫伤害"; break;
            case JXBtlBEM.ImDeBuff: str = "免疫减益"; break;
            case JXBtlBEM.ImDeCtrl: str = "免疫控制"; break;
            case JXBtlBEM.ClDamage: str = "清除伤害 "; break;
            case JXBtlBEM.ClDeBuff: str = "清除减益 "; break;
            case JXBtlBEM.ClCtl: str = "清除控制 "; break;
            case JXBtlBEM.ClAddHp: str = "清除治疗 "; break;
            case JXBtlBEM.ClBuff: str = "清除增益 "; break;
            case JXBtlBEM.ClIm: str = "清除免疫 "; break;
            case JXBtlBEM.RELife: str = "* 复活 "; break;
            case JXBtlBEM.LockHp: str = "生命锁定 "; break;
            case JXBtlBEM.ExEffect: str = "效果延长 "; break;
            case JXBtlBEM.Detonated: str = "效果引爆 "; break;
        }
        return "[" + str + ']';
    }
}